<template>
  <div class="ace-container">
    <!-- 官方文档中使用id，这里禁止使用，在后期打包后容易出现问题，使用 ref 或者 DOM 就行 -->
    <div class="ace-editor" ref="ace"></div>
  </div>
</template>

<script lang="ts">
import { defineComponent, } from "vue";
export default defineComponent({
  name: "CodeEditor",
  props: {
    modelValue: {
      type: String,
      //required: true
    },
    readonly: {
      type: Boolean,
      default: false,
    },
    mode: {
      type: String,
      default: "javascript",
    },
    userWorker: {
      //是否开启语法检查，默认开启
      type: Boolean,
      default: true,
    },
  },
  emits: ["update:modelValue"],
  mounted() {
    this.aceEditor = window.ace.edit(this.$refs.ace, {
      maxLines: 20, // 最大行数，超过会自动出现滚动条
      minLines: 5, // 最小行数，还未到最大行数时，编辑器会自动伸缩大小
      fontSize: 16, // 编辑器内字体大小
      theme: this.themePath, // 默认设置的主题
      mode: this.modePath, // 默认设置的语言模式
      tabSize: 4, // 制表符设置为2个空格大小
      readOnly: this.readonly,
      highlightActiveLine: true,
      value: this.codeValue,
    });

    this.aceEditor && (<{ setOptions: Function }>this.aceEditor).setOptions({
      enableBasicAutocompletion: true,
      enableSnippets: true, // 设置代码片段提示
      enableLiveAutocompletion: true, // 设置自动提示
    });

    if (this.mode === "json") {
      this.setJsonMode();
    } else if (this.mode === "css") {
      this.setCssMode();
    }

    if (!this.userWorker) {
      this.aceEditor && (<{ getSession: Function }>this.aceEditor).getSession().setUseWorker(false);
    }

    //编辑时同步数据
    this.aceEditor && (<{ getSession: Function }>this.aceEditor).getSession().on("change", (ev: any) => {
      this.$emit("update:modelValue", this.aceEditor && (<{ getValue: Function }>this.aceEditor).getValue());
    });
  },
  beforeMount() {
    let langTools = window.ace.require("ace/ext/language_tools");
    langTools.addCompleter({
      getCompletions: function (editor: any, session: any, pos: any, prefix: any, callback: (arg0: null, arg1: never[]) => any) {
        return callback(null, []);
      },
    });
  },
  data() {
    return {
      aceEditor: null,
      themePath: "ace/theme/monokai", // 不导入 webpack-resolver，该模块路径会报错
      modePath: "ace/mode/javascript", // 同上
      codeValue: this.modelValue,
    };
  },
  watch: {
    //
  },
  methods: {
    setJsonMode() {
      this.aceEditor && (<{ getSession: Function }>this.aceEditor).getSession().setMode("ace/mode/json");
    },

    setCssMode() {
      this.aceEditor && (<{ getSession: Function }>this.aceEditor).getSession().setMode("ace/mode/css");
    },

    getEditorAnnotations() {
      return this.aceEditor && (<{ getSession: Function }>this.aceEditor).getSession().getAnnotations();
    },

    setValue(newValue: any) {
      this.aceEditor && (<{ getSession: Function }>this.aceEditor).getSession().setValue(newValue);
    },
  },
});
</script>

<style  scoped>
.ace-editor {
  min-height: 300px;
}
</style>

<style>
.ace_tooltip {
  background-color: #2f3129;
  border: 1px solid #2f3129;
  color: gray;
  padding: 15px;
  font-size: 20px;
  font-family: "Trebuchet MS", "Lucida Sans Unicode", "Lucida Grande",
    "Lucida Sans", Arial, sans-serif;
}

.ace_tooltip b {
  color: #4e9e2d;
}

.ace_tooltip hr {
  border: 1px solid gray;
}
</style>
